package GSEA::FDR::ScoreNormalizer ;


use GSEA::Pvalue::Permutor ;

use strict ;
use warnings;

sub constrScoreNormalizer($$$$$) #constructor
{
	my ($classe , $Nhit ,  $L_table , $Npermutations , $Pparameter ) = @_; 
	
	
	if( ! defined($Nhit 	 	)	){ die("argument 'Nhit' is not set , error");}	
	if( ! defined($L_table 	 	)	){ die("argument 'L_table' is not set , error");}
	if( ! defined($Npermutations)	){ die("argument 'Npermutations' is not set , error");}
	if( ! defined($Pparameter	) 	){ die("argument 'Pparameter' is not set , error");}

	
	my $this = {
					"Nhit"			=> $Nhit		 ,
					"L_table"		=> $L_table		 ,
					"Npermutations"=> $Npermutations,					
					"Pparameter"	=> $Pparameter	 
				};
	
	bless ($this,$classe);  
		
	return $this; 
}

sub normalizeScore($$)
{
	( my $this , my $score) = @_ ;
	
	my $permutor = GSEA::Pvalue::Permutor->constrPermutor( $this->{"Nhit"} , $this->{"L_table"}  , $this->{"Npermutations"} , $this->{"Pparameter"} );
	
	my @scores = $permutor->getScores();
	#@scores = sort{ $b <=> $a  } @scores ;
	
	# average computing
	my $NegCp  = 0 ;
	my $PosCp  = 0 ;
	my $NegAve = 0 ;
	my $PosAve = 0 ;
	
	for( my $j= 0 ; $j< @scores ; $j++ )
	{
		if( $scores[$j] < 0 )
		{
			$NegCp++;
			$NegAve += $scores[$j] ;
		}
		else
		{
			$PosCp++;
			$PosAve += $scores[$j] ;			
		}
	}
	
	
	$NegAve = $NegAve / $NegCp ;
	$PosAve = $PosAve / $PosCp ;
	
	
	my $NES = 0 ;
	if( $score < 0 ){ $NES = $score / $NegAve ; }
	else			{ $NES = $score / $PosAve ; }
	
	#print("\nscore=$score // negave=$NegAve  posave=$PosAve // NES=$NES");
	
	# computing the "Normalized P-value"
	my $npv = 0 ;
	for( my $j= 0 ; $j< @scores ; $j++ )
	{
		# calculating the NES of the current score
		my $currentNES = 0;
		if( $scores[$j] < 0 )
		{
			$currentNES = $scores[$j] / $NegAve ;
		}
		else
		{
			$currentNES = $scores[$j] / $PosAve ;			
		}
		
		
		#print("\nscore ". $scores[$j] . " currentNES=$currentNES " );
		
		# if they have the same sign , and if the currentNES is greater -> increase the counter
		if( ($score<0) == ($scores[$j]<0)  &&  abs($NES)<abs($currentNES)  )
		{
			$npv++;
			#print("  ok ")
		}

		
	}	
	
	my $NormPvalue = 1 ;
	if( $NES < 0  )
	{
		$NormPvalue = $npv / $NegCp ;
	}
	else
	{
		$NormPvalue = $npv / $PosCp ;
	}
	
	#print("\nnormalized pvluae = $NormPvalue");
	
	return ( $NES , $NormPvalue ) ;	
}

1;
